#include"Log.hpp"
#include<cstring>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#define BACKLOG 5

class TcpServer
{
  private:
   int _port;
   int _sock;
  private:
   void CreateSocket()
   {
     _sock=socket(AF_INET,SOCK_STREAM,0);
     if(_sock<0)
     {
       LOG(FATAL,"CreateSocket Error!");
       exit(1);
     }
     LOG(INFO,"CreateSocket Success");

     int opt=1;
     setsockopt(_sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
   }

   void Bind()
   {
     struct sockaddr_in  peer;     
     memset(&peer,0,sizeof(peer));
     peer.sin_family=AF_INET;
     peer.sin_addr.s_addr=INADDR_ANY; 
     peer.sin_port=htons(_port);
     socklen_t len=sizeof(peer);

     if(bind(_sock,(struct sockaddr*)&peer,len)<0)
     {
       LOG(FATAL,"Bind Error!");
       exit(2);
     }

     LOG(INFO,"Bind Success");
   }

   void Listen()
   {
     if(listen(_sock,BACKLOG)<0)
     {
       LOG(FATAL,"Listen Error!"); 
       exit(3);
     }

     LOG(INFO,"Listen Success");
   }

  public:
   TcpServer(int port):_port(port),_sock(-1)
   {}

   ~TcpServer()
   {
     if(_sock>0)
       close(_sock);
   }

   void Init()
   {
      CreateSocket();

      Bind(); 

      Listen();
      
      LOG(INFO,"TcpServer Init Success");
   }

   int Accept(struct sockaddr_in* peer=nullptr,socklen_t* len=nullptr)
   {
     int ret = accept(_sock,(struct sockaddr*)peer,len);
     return ret;
   }



};
